#include <jni.h>
#include <string>
#include <opencv2/opencv.hpp>
#include <assert.h>
#include <android/bitmap.h>
#include <Android/log.h>
#include "header/native-lib.h"
//#include "demo_edgedetection_EdgeDetection.h"
//#include "getpaperpoints/GetPaperPoints.h"
#include <vector>


//方法名必须为本地方法的全类名点改为下划线，穿入的两个参数必须这样写，
//第一个参数为Java虚拟机的内存地址的二级指针，用于本地方法与java虚拟机在内存中交互
//第二个参数为一个java对象，即是哪个对象调用了这个c方法

using namespace std;
using namespace cv;

extern "C"{
    jstring
    Java_com_example_tanlee_ocrgraduation_activity_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject /* this */) {
        std::string hello = "写个C++感受一下";
        cv::Mat;
        return env->NewStringUTF(hello.c_str());
    }


    JNIEXPORT jintArray JNICALL
    Java_com_example_tanlee_ocrgraduation_activity_MainActivity_rgbToGray(JNIEnv *env, jobject instance,
                                                                          jobject bitmapImage) {
        // TODO
        AndroidBitmapInfo bitmapImageInfo;
        void* bitmapImagePixels;
        int width,height,ret;
        //解析bitmap
        if((ret = AndroidBitmap_getInfo(env, bitmapImage, &bitmapImageInfo)) < 0){
            LOGD("AndroidBitmap_getInfo() failed ! error=%d", ret);
            return 0;
        }
        if(bitmapImageInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888){
            LOGD("Bitmap format is not RGBA_8888!");
            return 0;
        }
        if ((ret = AndroidBitmap_lockPixels(env, bitmapImage, &bitmapImagePixels)) < 0) {
            LOGD("Bitmap LockPixels Failed return=%d!", ret);
            return 0;
        }

        int h = bitmapImageInfo.height;
        int w = bitmapImageInfo.width;

        CV_Assert( AndroidBitmap_lockPixels(env, bitmapImage, &bitmapImagePixels) >= 0 );
        CV_Assert( bitmapImagePixels );

        //以上实现了bitmap的解析，得到bitmapImagePixels的指针
        //RGBA_8888正好与opencv CV_8UC4对应，不用逐像素操作了
        //下面将bitmap转化为mat格式
        width = bitmapImageInfo.width;
        height = bitmapImageInfo.height;
        cv::Mat image(height, width, CV_8UC4, bitmapImagePixels);
        cvtColor(image,image,CV_RGBA2GRAY);
        AndroidBitmap_unlockPixels(env, bitmapImage);
        return 0;
    }

    JNIEXPORT jintArray JNICALL
    Java_com_example_tanlee_ocrgraduation_activity_MainActivity_rgb2Gray(JNIEnv *env, jobject instance,
                                                                         jintArray buf,
                                                                         jint height, jint width) {
        jint *cbuf;
        cbuf = env->GetIntArrayElements(buf, JNI_FALSE );
        if (cbuf == NULL) {
            return 0;
        }
        Mat imgData(height, width, CV_8UC4, (unsigned char *) cbuf);
        uchar* ptr = imgData.ptr(0);
//        for(int i = 0; i < width*height; i ++){
//            //计算公式：Y(亮度) = 0.299*R + 0.587*G + 0.114*B
//            //对于一个int四字节，其彩色值存储方式为：BGRA
//            int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
//            ptr[4*i+1] = grayScale;
//            ptr[4*i+2] = grayScale;
//            ptr[4*i+0] = grayScale;
//        }
        cvtColor(imgData,imgData,CV_RGB2GRAY);
        int size = width * height;
        int* outImage = new int[size];
        for(int i=0;i<size;i++){
            outImage[i] = (int) imgData.data[i];
        }
        jintArray result = env->NewIntArray(size);
        env->SetIntArrayRegion(result, 0, size, outImage);
        env->ReleaseIntArrayElements(buf, cbuf, 0);
        return result;
    }

}
